home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
basic
/
qbnws105.zip
/
QBFORMAT.ZIP
/
INTRPT.ASM
next >
Wrap
Assembly Source File
|
1989-03-14
|
15KB
|
366 lines
TITLE INTERRUPT - BASCOM software interrupt calling routine
PAGE 56,132
;***
; INTERRUPT - BASCOM software interrupt calling routine
;
; Copyright <C> 1986, 1987 Microsoft Corporation
;
;Purpose:
; Allows a BASIC program to invoke an interrupt through a CALL statement.
;
; INTERRUPT allows BASIC to set AX,BX,CX,DX,BP,SI,DI, and the flags
; before the call. INTERRUPTX also allows DS and ES to be set.
; Both routines will return the values of the registers upon the
; completion of a successful call. If the interrupt could not
; be generated (due to a bad interrupt number or an illegal array)
; then the interrupt number will be set to -1 to indicate an error.
;
;******************************************************************************
;
;Note:
; The DOSSEG, .MODEL, .CODE, and .DATA? directives used in this program
; are part of the simplified segment system of MASM 5.0. If you have
; an earlier version of MASM, you must modify the source to define
; the segments required by Microsoft high-level languages. These
; segments are discussed in Appendix C of "Learning and Using QuickBASIC."
;
; Frame structure definition
ARG1 = 0AH ;pointer to first of three arguments
ARG2 = 08H ;pointer to second of three arguments
ARG3 = 06H ;pointer to third of three arguments
; Frame temp variables
UCODE_FLGS = -02H ;user code flag register value
UCODE_DS = -04H ;user code DS register value
REG_NUM = -06H ;number of regs used (INTERRUPT=8, INTERRUPTX=10)
INT_ES = -08H ;INT ES register value
INT_DS = -0AH ;INT DS register value
INT_FLGS = -0CH ;INT flags register value
INT_DI = -0EH ;INT DI register value (was -1EH, bug)
INT_SI = -10H ;INT SI register value
INT_BP = -12H ;INT BP register value
INT_DX = -14H ;INT DX register value
INT_CX = -16H ;INT CX register value
INT_BX = -18H ;INT BX register value
INT_AX = -1AH ;INT AX register value
OLD_SI = -1CH ;save old SI for interpreter
OLD_DI = -1EH ;save old DI for interpreter
FRM_SIZ = -1EH ;negative size of frame temporaries
; Locations past frame allocation used to recover post-INT BP value.
INT_BP_TMP = -22H ;temp location for INT BP register value
;***
; INTERRUPT, and INTERRUPTX - BASCOM software interrupt calling interface
;
; Purpose:
; To allow a BASIC Compiler program to perform any software
; interrupt. The interrupt is executed with the registers
; set to values specified in a register variable. The post-
; interrupt values of the registers are then stored in
; another register RegType[X],
; outreg AS RegType[X])
;
; Inputs:
; int_no = interrupt number (range 0 to 255) to execute
; inreg and outreg are register variables of type RegType[X]
; defined as follows;
;
; TYPE RegType
; ax AS INTEGER
; bx AS INTEGER
; cx AS INTEGER
; dx AS INTEGER
; bp AS INTEGER
; si AS INTEGER
; di AS INTEGER
; flags AS INTEGER
; END TYPE
;
;
; TYPE RegTypeX
; ax AS INTEGER
; bx AS INTEGER
; cx AS INTEGER
; dx AS INTEGER
; bp AS INTEGER
; si AS INTEGER
; di AS INTEGER
; flags AS INTEGER
; ds AS INTEGER
; es AS INTEGER
; END TYPE
;
; Outputs:
; If no error:
; int_no = unchanged (range 0 to 255)
; outreg: This array will be set to the post-interrupt
; register values. It has the same structure
; as inreg.
; If error:
; int_no = -1
; outreg unchanged. INT call is not performed.
; error occurs:
; first argument not 0 to 255 (2^8-1)
; second or third arguments not 0 to 1048575 (2^20-1)
; (VARPTR will always be in this range)
;
; Modifies:
; All, except BP, DS, and flags.
; Also, possible side effects of INT call.
;
; Exceptions:
; INT 24H call may result from some INT 21H MS-DOS calls.
;
;******************************************************************************
_bss segment word PUBLIC 'data'
_bss ends
_data segment word PUBLIC 'data'
_data ends
dgroup group _bss, _data
Intrpt_TEXT segment word PUBLIC 'code'
assume cs:Intrpt_TEXT, ds:dgroup, es:dgroup, ss:dgroup
PUBLIC INTERRUPT
INTERRUPT PROC FAR
PUSH BP ;save BASCOM frame pointer on stack
MOV BP,SP ;establish program frame reference
ADD SP,FRM_SIZ ;allocate working space for frame
MOV WORD PTR [BP].REG_NUM,08H ;eight regs used (not DS or ES)
JMP SHORT INTERRUPT_COMMON ;jump to common code
INTERRUPT ENDP
PUBLIC INTERRUPTX
INTERRUPTX PROC FAR
PUSH BP ;save BASCOM frame pointer on stack
MOV BP,SP ;establish program frame reference
ADD SP,FRM_SIZ ;allocate working space for frame
MOV WORD PTR [BP].REG_NUM,0AH ;ten regs used (including DS and ES)
; Save a copy of the processor flags, SI, DI, and DS in the stack frame.
INTERRUPT_COMMON:
MOV [BP].OLD_SI,SI ;save old SI for interpreter
MOV [BP].OLD_DI,DI ;save old DI for interpreter
MOV [BP].UCODE_DS,DS;save DS for interpreter
PUSHF ;push the flags on the stack
POP [BP].UCODE_FLGS ;put value in the stack frame
; Move eight or ten words (depending if executing INTERRUPT or INTERRUPTX)
; of the integer input array from the far pointer computed to the frame.
MOV SI,[BP].ARG2 ;and array offset - pointer in DS:SI
LEA DI,[BP].INT_AX ;get start of temporary register storage.
MOV CX,[BP].REG_NUM ;eight or ten words to move
CLD ;movement is to higher memory
PUSH SS
POP ES
REP MOVSW ;move the array into the stack frame
; Save stack frame pointer to recover its value after the INT call.
PUSH BP ;saved to first word past the stack frame
; Create a two-instruction program on the stack to execute the
; INT call requested and return with stack cleanup.
;
; INT XX (hex: CD XX)
; RETF 06 (hex: CA 06 00)
;
; In the case of INT 25 and 26 (which leave a word of flags on the stack)
; We generate:
;
; INT XX (hex: CD XX)
; ADD SP,2 (hex: 83 C4 02) ;this trashes ALL math flags incl CF
; RETF 08 (hex: CA 08 00)
;----------debugged--- CHH solution
; INT XX (hex: CD XX)
; inc sp (hex: 44)
; inc sp (hex: 44)
; nop (hex: 90)
; RETF 08 (hex: CA 08 00)
;
MOV SI,[BP].ARG1 ;[SI] = ptr to first CALL arg - interrupt #
MOV BX,[SI] ;[BL] = get integer value of INT type
OR BH,BH ;test if in range, 00 to FFH is legal
JZ NO_INT_ERROR ;if not, then error - jump
JMP INT_ERROR ;long jump to error routine
NO_INT_ERROR:
CMP BL,25H ;Interrupt 25 request?
JZ Int2526 ;Jump if so
CMP BL,26H ;Interrupt 26 request?
JNZ IntNorm ;Jump if other, "normal" interrupt
Int2526:
MOV AX,8 ;[AX] = argument of RETF instructi